#include "balance.h"
#include "scope_protocol.h"

#define SCOPE_SERIAL_NAME "uart1"

static rt_device_t serial;                 /* 输出串口 */
static rt_thread_t uart2_thread = RT_NULL; /* 姿态更新线程 */
static struct rt_semaphore rx_sem;         /* 串口接收信号量 */

enum RX_STATE
{
    RX_STATE_IDLE,
    RX_STATE_READY,
} state;

uint8_t uart2_tx_buffer[] = {PROTOCOL_HEADER, PROTOCOL_COMMAND_REPORT, PROTOCOL_CHANNEL_1,
                             0x00, 0x00, 0x00, 0x00}; //发送缓冲
rt_uint8_t uart2_rx_buffer[7];                        //接收缓冲
rt_uint32_t ptr = 0;                                  //接收指针

/**
 * 数据上报
 */
void protocol_report_data(uint8_t ch, float value)
{
    int i = 0;
    uart2_tx_buffer[2] = ch;
    uint8_t *addr = (uint8_t *)&value;
    for (i = 0; i < 4; i++)
    {
        uart2_tx_buffer[i + 3] = addr[i];
    }
    rt_device_write(serial, 0, uart2_tx_buffer, 7);
}

/**
 * 串口2接收中断
 */
static rt_err_t uart2_rx_irq(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&rx_sem);
    return RT_EOK;
}

/**
 * 串口2接收线程
 */
static void uart2_thread_entry(void *parameter)
{
    char ch;
    while (1)
    {
        /* 从串口读取一个字节的数据，没有读取到则等待接收信号量 */
        while (rt_device_read(serial, -1, &ch, 1) != 1)
        {
            /* 阻塞等待接收信号量，等到信号量后再次读取数据 */
            rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
        }
        /* 读取到的数据通过串口错位输出 */
        switch (state)
        {
        case RX_STATE_IDLE:
            if (ch == 0x55)
            {
                ptr = 0;
                uart2_rx_buffer[ptr++] = ch;
                state = RX_STATE_READY;
            }
            break;
        case RX_STATE_READY:
            uart2_rx_buffer[ptr++] = ch;
            if (ptr >= 7)
            {
                //数据处理
                if (uart2_rx_buffer[1] == 0x02) //写通道数据
                {
                    if (uart2_rx_buffer[2] == 0x01)
                    {
                        info.balanceKp = *((float *)&uart2_rx_buffer[3]);
                    }
                    if (uart2_rx_buffer[2] == 0x02)
                    {
                        info.balanceKd = *((float *)&uart2_rx_buffer[3]);
                    }
                    if (uart2_rx_buffer[2] == 0x03)
                    {
                        info.velocityKp = *((float *)&uart2_rx_buffer[3]);
                    }
                    if (uart2_rx_buffer[2] == 0x04)
                    {
                        info.velocityKi = *((float *)&uart2_rx_buffer[3]);
                    }
                }
                state = RX_STATE_IDLE;
            }
            break;
        default:
            break;
        }
    }
}

/**
 * 串口2初始化
 */
static int uart2_init(const char *name)
{
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);

    serial = rt_device_find(SCOPE_SERIAL_NAME);
    if (!serial)
    {
        rt_kprintf("find %s failed!\n", SCOPE_SERIAL_NAME);
        return RT_ERROR;
    }
    rt_device_close(serial);
    rt_device_set_rx_indicate(serial, uart2_rx_irq); //设置接收回调函数
    rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
    uart2_thread = rt_thread_create("uart2_thread",
                                    uart2_thread_entry,
                                    RT_NULL,
                                    THREAD_STACK_SIZE,
                                    20,
                                    THREAD_TIMESLICE);
    if (uart2_thread != RT_NULL)
    {
        rt_thread_startup(uart2_thread);
    }
    return 0;
}
INIT_APP_EXPORT(uart2_init);